/*******************************************************************************
 * Witz - Winboard Chess Engine                                                *
 * PROTOS.H                                                                    *
 *                                                                             *
 * Provides an outline of all the functions in each module by giving prototype *
 * defenitions for all the functions in each module.                           *
 *                                                                             *
 * Please refer to the licence notice in MAIN.C                                *
 *                                                                             *
 * Copywright (C) 2006 Pradu Kannan                                            *
 * http://witz.sf.net/                                                         *
 ******************************************************************************/

#ifndef __protos
#define __protos

//BITINSTRUCTIONS.C
int popCount(const U64 b);
int iterativePopCount(U64 b);
int Log2(const U64 x);
U64 fillUp(U64 b);
U64 fillDown(U64 b);
U64 fillUp2(U64 b);
U64 fillDown2(U64 b);

//BOARD.C
void initializeBoard();
void nullBoard();
void inferRestOfBoard();
bool setBoard(char* FEN);
void addPiece(bool color, char type, int square);
void clearSquare(int square);
void changeColor(int square);
bool isIllegalPosition();
bool makeGameTakeback();
U64 makeGameMove(const move m);
U64 makemove(board* pos, const move m);
bool gameEnded();
bool isPinnedToK(const board* pos, char square);
bool isDirPinnedToK(const board* pos, char square, char dirsq);

//BOOK.C
void createBook(int argc, char *argv[]);
bool findInBook(board *pos, bookPosition *bookPos);
move getBookMove();
void openBook();
void closeBook();

void openPGN(pgnFile* pgn, char* path);
void closePGN(pgnFile* pgn);
bool nextPosition(pgnFile* pgn, pgnPosition* pgnPos);

void rb_insert(bookPosition* bookPos);
bool bianaryInsert(rbNode* root, rbNode* node);
void rbVerify(rbNode* n);
void rb_rotateLeft(rbNode* n);
void rb_rotateRight(rbNode* n);
bool rbGetLeast(rbNode* n, bookPosition* bookPos);

//CONFIG.C
void readConfig();
void writeDefaultValues();
void stringToUpperCase(char* string);
bool read64IntArray(int arr[64]);
void write64IntArray(int arr[64]);
void copyArray(int* arrCopy, int* arrOriginal, int size);

//DATABASEGEN.C
void generateDatabases();
void generateToBitsandShifts();
void generateSilderBitBase();
void generateKNPmoves();
void generatePlusNMinusN();
void generateLogTable();
void generatePopulation();
void generateZobrist();
void generateCastlingBits();
void generateSEEdir();
void generateSEEocc();
void generateSEEpiece();
void generateDetectPasser();
void generateKingStopsPasser();
void generateDistance();

//EVAL.C
void printEval(const board* pos);
int eval(const board* pos);
int mobility(const board* pos, U64* pawnAttacks, U64* diagAttacks, U64* rookAttacks, U64* knightAttacks);
int kingsafety(const board* pos, const U64* pawnAttacks, const U64* diagAttacks, const U64* rookAttacks, const U64* knightAttacks, const int* pieceMaterial);
int pawnEval(const board* pos, const U64* pawnAttacks, const U64* diagAttacks, const U64* rookAttacks, const U64* knightAttacks);
bool decidable(const board* pos, const drawEntry* drawTable, const short dfr, int* result);

//HASH.C
void resetTT();
void recordTT(const board* pos, move m, int score, char flag, short d, short dfr);
bool probeTT(const board* pos, TTprobe* tt_probe);
void dumpState();
void loadState(char* filename);

//MAIN.C
bool setOpenedInConsole();
bool checkInput();
void printLicenceStatement();
void printWinboardNotice();
void printShowW();
void printShowC();
void printPrompt();
void quit();
int getNoProcessors();

//MOVEGEN.C
void generateLegalMoves(const board* pos, moveList* list);
U64 Pmove(const board* pos, const char square);
void generatePerftMoves(const board* pos, moveList* list);
void generateMoves(const board* pos, moveList* list);
void generateGoodCaptures(const board* pos, moveList* list);

//MOVEORDERING.C
void resetHH();
void resetKillers();
void updateHH(move m, const short d);
void updateKiller(move m, const short dfr);
int findHH(move m);

#ifdef sort
	#undef sort
#endif
void sort(moveList* list);
int scoreMove(const board* pos, move m);

//MT19937-64.C
void seedMT();
void srand64(U64 seed);
void sarrayrand64(U64 init_key[], int key_length);
U64 rand64(void);

//PST.C
void printPCSQ();
void generatePieceSquare(board* pos);

//SEARCH.C
move getBestMove(void* depth);
void ponder();
U64 perft(const char d);
void perftHelper(board pos, const move m, const char d);
smove pvsStart(int alpha, int beta, short depth);
int pvs(int alpha, int beta, move m, board pos, short depth, short dfr, drawEntry* drawTable);
int horizonScore(int alpha, int beta, board* pos);
int qsearch(int alpha, int beta, move capture, board pos);
int checkEvasion(int alpha, int beta, board *pos);
bool tryNull(const board* pos, const bool tt_hit, const TTprobe* tt_probe, const short depth);
U16 adaptiveR(const board* pos, const short depthleft);

smove alphabetaStart(int alpha, int beta, short depth);
int alphabeta(int alpha, int beta, move m, board pos, short depth, short dfr, drawEntry* drawTable);
int ABhorizonScore(int alpha, int beta, const board* pos);
int ABqsearch(int alpha, int beta, move capture, board pos);
int ABcheckEvasion(int alpha, int beta, board *pos);
int startStaticSearch(int alpha, int beta, board* pos, short depth, short dfr, drawEntry* drawTable);

#ifdef max
	#undef max
#endif
#ifdef min
	#undef min
#endif

int max(int a, int b);
int min(int a, int b);

//SEE.C
int SEE(const board* pos,move m);
U8 SEEocca1h8(const board* pos, const char square);
U8 SEEocch1a8(const board* pos, const char square);
U8 SEEoccrank(const board* pos, const char square);
U8 SEEoccfile(const board* pos, const char square);
U8 SEEoccdummy(const board* pos, const char square);
int MVVLVA(move m);
int fastSEE(const board* pos,move m);

//TIMEMANAGER.C
int getms();
void startClock();
bool timesUp();

//WINBOARD.C
void xboard();
char evaluvateCommand(char* line);

int charToPiece(char piece);
char coordsToSquare(char col, char row);
int colPart(char col);
int rowPart(char row);
char* moveToString(move m);
char* moveToSAN(const board* pos, move m);
char* moveToSANHelper(const board* pos, U64 temp3, char from, char to);
char* moveToCBSAN(const board* pos, move m);
char* moveToCBSANHelper(const board* pos, U64 temp3, char from, char to);
move parseMove(const char* s);
move parseLegalMove(const char* moveString, const board* pos);
char ColCoord(int x);
char RowCoord(int x);
char* getCoord(int x);
char PieceToCharLowercase(int x);
char PieceToCharUppercase(int x);

bool looksLikeAMove(const char *s);
void printBoard();
void printWB2compatibility();
bool edit();
void analyze();
void printResult(char side, char* comment);
void printHelp();

void initializeEngine();
char* toDecimal(U64 x);
void printPV();
void printVariation(move m);
void printHashLine(move m);

#endif

